/*
 *  WaveFunctionTester.cpp
 *  SoundController0002
 *
 *  Created by jiro on 10/11/13.
 *  Copyright 2010 jiro music. All rights reserved.
 *
 */

#include "WaveFunctionTester.h"

namespace sc {

	void WaveFunctionTester::TestAll()
	{
		Test_001();

		Test_002();

		Test_003();

		Test_004();

		Test_005();

		Test_006();

		Test_007();
	}

	void WaveFunctionTester::Test_001()
	{
		double length = 1.5;
		double powerOfX = 1;
		const WaveFunction& function = WaveFunctionFactory::CreateXSinX( powerOfX, 2 * length );
		double delta = 0.00001;
		double time = 0;
		for ( ; time < 2 * length; time += delta ) {
			AssertTrue( function( time ) >= 0 );
		}
		AssertEqualWithError( function( length ), 0, 0.000001 );
		AssertEqualWithError( function.GetMaxOfY(), 1.0, 0.000001 );
	}

	void WaveFunctionTester::Test_002()
	{
		double length = 1.5;
		double powerOfX = 1;
		const WaveFunction& function = WaveFunctionFactory::CreateXSinX( powerOfX, length, true );
		const WaveFunctionXSinX& ref = dynamic_cast<const WaveFunctionXSinX&>( function );

		AssertEqual( ref.GetPowerOfX(), 1 );
		AssertEqual( ref.GetInterceptOfX(), 0.75 );
		AssertEqual( ref.GetSlopeOfX(), -1 );

	}

	void WaveFunctionTester::Test_003()
	{
		double length = 1.5;
		double powerOfX = 1;
		const WaveFunction& function = WaveFunctionFactory::CreateXSinX( powerOfX, length );
		const WaveFunction& functionRev = WaveFunctionFactory::CreateXSinX( powerOfX, length, true );

		const WaveFunctionXSinX& ref = dynamic_cast<const WaveFunctionXSinX&>( function );
		const WaveFunctionXSinX& refRev = dynamic_cast<const WaveFunctionXSinX&>( functionRev );

		double delta = 1 / Sampling_Rate_As_Double;
		double time = delta;
		for ( ; time < length; time += delta ) {
			float value = ref( time );
			float valueRev = refRev( length - time );
			AssertEqual( value, valueRev );
			if ( value != valueRev ) {
				cout << "time: " << time << endl;
			}
		}
	}

	void WaveFunctionTester::Test_004()
	{
		const double length = 2.0;
		const double power = 1.2;
		const WaveFunction& func = WaveFunctionFactory::CreateLogXSinX( power, length, false );
		const WaveFunction& funcRev = WaveFunctionFactory::CreateLogXSinX( power, length, true );
		const WaveFunctionLogXSinX& ref = dynamic_cast<const WaveFunctionLogXSinX&>( func );
		const WaveFunctionLogXSinX& refRev = dynamic_cast<const WaveFunctionLogXSinX&>( funcRev );

		AssertEqual( ref.GetCycle(), 1.0 / length );
		AssertEqual( refRev.GetCycle(), 1.0 / length );
		AssertEqual( ref.GetMaxOfY(), 1.0 );
		AssertEqual( refRev.GetMaxOfY(), 1.0 );
		AssertEqual( ref.GetPowerOfXOfLog(), power );
		AssertEqual( refRev.GetPowerOfXOfLog(), power );

		double time = 0;
		double delta = 1.0 / Sampling_Rate_As_Double;
		for ( ; time < length; time += delta ) {

			AssertEqualWithError( func( time ), funcRev( length - time ), 0.0000001 );
			AssertTrue( func( time ) >= 0 );
			AssertTrue( func( time ) <= 1 );
			AssertTrue( funcRev( time ) >= 0 );
			AssertTrue( funcRev( time ) <= 1 );
		}
	}

	void WaveFunctionTester::Test_005()
	{
		const WaveFunction& func = WaveFunctionFactory::CreateSinXVariableCycle( Line::Type_Straight, 100, 200, 0, 1 );
		const WaveFunctionSinXVariableCycle& ref = dynamic_cast<const WaveFunctionSinXVariableCycle& >( func );
		AssertEqual( ref.GetStartCycle(), 100 );
		AssertEqual( ref.GetEndCycle(), 200 );
		AssertEqual( ref.GetCycle( 0 ), 100 );
		AssertEqual( ref.GetCycle( 1 ), 200 );
	}


	void WaveFunctionTester::Test_006()
	{
		const WaveFunction& func = WaveFunctionFactory::CreateSinXVariableCycle( Line::Type_Straight, 200, 100, 0, 1 );
		const WaveFunctionSinXVariableCycle& ref = dynamic_cast<const WaveFunctionSinXVariableCycle& >( func );
		AssertEqual( ref.GetStartCycle(), 200 );
		AssertEqual( ref.GetEndCycle(), 100 );
		AssertEqual( ref.GetCycle( 0 ), 200 );
		AssertEqual( ref.GetCycle( 1 ), 100 );
	}

	void WaveFunctionTester::Test_007()
	{
		double length = 2;
		const WaveFunction& func = WaveFunctionFactory::CreateSinXVariableCycle( Line::Type_Straight, 880, 440, 0, length );
		const WaveFunctionSinXVariableCycle& ref = dynamic_cast<const WaveFunctionSinXVariableCycle& >( func );
		AssertEqual( ref.GetStartCycle(), 880 );
		AssertEqual( ref.GetEndCycle(), 440 );
		AssertEqual( ref.GetCycle( 0 ), 880 );
		AssertEqual( ref.GetCycle( length ), 440 );
		double delta = 1 / Sampling_Rate_As_Double;
		for ( double t = 0; t <= length; t += delta ) {
			AssertLessOrEqual( ref.GetCycle( t ), 880 );
			AssertGreaterOrEqual( ref.GetCycle( t ), 440 );
		}
	}
}